home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / BC++ Builder / DATA.Z / VARIANT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-10  |  45.8 KB  |  2,011 lines

  1. //---------------------------------------------------------------------------
  2. //    variant.cpp - support for delphi variants in cpp
  3. //---------------------------------------------------------------------------
  4. // $Revision:   1.44  $
  5. //-------------------------------------------------------------------------
  6. //    copyright (c) 1997 Borland International
  7. //----------------------------------------------------------------------------
  8. #pragma inline
  9.  
  10. #include<windows.hpp>
  11. #include<ole2.hpp>
  12. #include<oleauto.hpp>
  13. #include <sysutils.hpp>
  14. #include "variant.hpp"
  15.  
  16. #ifdef near
  17. #undef near
  18. #endif
  19.  
  20. namespace System
  21. {
  22.  
  23. //---------------------------------------------------------------------------
  24.  
  25. //statics
  26. Variant __fastcall Variant::CreateObject(const String& ProgID)
  27. {
  28.   return Oleauto::CreateOleObject(const_cast<String&>(ProgID));
  29. }
  30.  
  31. Variant __fastcall Variant::GetActiveObject(const String& ProgID)
  32. {
  33.   return Oleauto::GetActiveOleObject(const_cast<String&>(ProgID));
  34. }
  35.  
  36. //ctors
  37. __fastcall Variant::Variant()
  38. {
  39.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  40. }
  41.  
  42. __fastcall Variant::Variant(const Variant& rhs)
  43. {
  44.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  45.  
  46.   System::VarCopyNoInd(*this, rhs);
  47. }
  48.  
  49. __fastcall Variant::Variant(const short src)
  50. {
  51.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  52.   VType = varSmallint;
  53.   VSmallint = src;
  54. }
  55.  
  56. __fastcall Variant::Variant(const int src)
  57. {
  58.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  59.   VType = varInteger;
  60.   VInteger = src;
  61. }
  62.  
  63. __fastcall Variant::Variant(const float src)
  64. {
  65.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  66.   VType = varSingle;
  67.   VSingle = src;
  68. }
  69.  
  70. __fastcall Variant::Variant(const double src)
  71. {
  72.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  73.   VType = varDouble;
  74.   VDouble = src;
  75. }
  76.  
  77. __fastcall Variant::Variant(const Currency src)
  78. {
  79.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  80.   VType = varCurrency;
  81.   VCurrency = src;
  82. }
  83.  
  84. __fastcall Variant::Variant(const TDateTime src)
  85. {
  86.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  87.   VType = varDate;
  88.   VDate = src;
  89. }
  90.  
  91. __fastcall Variant::Variant(const bool src)
  92. {
  93.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  94.   VType = varBoolean;
  95.   VBoolean = src;
  96. }
  97.  
  98. __fastcall Variant::Variant(const WordBool src)
  99. {
  100.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  101.   VType = varBoolean;
  102.   VBoolean = src;
  103. }
  104.  
  105. __fastcall Variant::Variant(const Byte src)
  106. {
  107.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  108.   VType = varByte;
  109.   VByte = src;
  110. }
  111.  
  112. __fastcall Variant::Variant(const String& src)
  113. {
  114.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  115.   VType = varString;
  116.   VString = 0;
  117.   (AnsiString&)VString = src;
  118. }
  119.  
  120. __fastcall Variant::Variant(const char* src)
  121. {
  122.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  123.   VType = varString;
  124.   VString = 0;
  125.   (AnsiString&)VString = src;
  126. }
  127.  
  128. __fastcall Variant::Variant(wchar_t* const src)
  129. {
  130.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  131.   VType = varOleStr;
  132.   VOleStr = SysAllocString(src);
  133. }
  134.  
  135. __fastcall Variant::Variant(Ole2::IDispatch* const src)
  136. {
  137.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  138.   VType = varDispatch;
  139.   if (src)
  140.     src->AddRef();
  141.   VDispatch = src;
  142. }
  143.  
  144. __fastcall Variant::Variant(Ole2::IUnknown* const src)
  145. {
  146.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  147.   VType = varUnknown;
  148.   if (src)
  149.     src->AddRef();
  150.   VUnknown = src;
  151. }
  152.  
  153. //ByRef constructors
  154. __fastcall Variant::Variant(short* src)
  155. {
  156.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  157.   VType = varSmallint | varByRef;
  158.   VPointer = src;
  159. }
  160.  
  161. __fastcall Variant::Variant(int* src)
  162. {
  163.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  164.   VType = varInteger | varByRef;
  165.   VPointer = src;
  166. }
  167.  
  168. __fastcall Variant::Variant(float* src)
  169. {
  170.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  171.   VType = varSingle | varByRef;
  172.   VPointer = src;
  173. }
  174.  
  175. __fastcall Variant::Variant(double* src)
  176. {
  177.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  178.   VType = varDouble | varByRef;
  179.   VPointer = src;
  180. }
  181.  
  182. __fastcall Variant::Variant(Currency* src)
  183. {
  184.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  185.   VType = varCurrency | varByRef;
  186.   VPointer = src;
  187. }
  188.  
  189. __fastcall Variant::Variant(TDateTime* src)
  190. {
  191.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  192.   VType = varDate | varByRef;
  193.   VPointer = src;
  194. }
  195.  
  196. __fastcall Variant::Variant(WordBool* src)
  197. {
  198.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  199.   VType = varBoolean | varByRef;
  200.   VPointer = src;
  201. }
  202.  
  203. __fastcall Variant::Variant(Byte* src)
  204. {
  205.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  206.   VType = varByte | varByRef;
  207.   VPointer = src;
  208. }
  209.  
  210. __fastcall Variant::Variant(wchar_t** src)
  211. {
  212.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  213.   VType = varOleStr | varByRef;
  214.   VPointer = src;
  215. }
  216.  
  217. //construct a Variant array of type varType
  218. __fastcall Variant::Variant(const int* bounds,const int boundsSize,Word varType)
  219. {
  220.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  221.  
  222.   *this = System::VarArrayCreate(bounds, boundsSize, varType);
  223. }
  224.  
  225. // construct a one dimensional Variant array of type varVariant
  226. // and fill with values
  227. __fastcall Variant::Variant(const Variant* values, const int valuesSize)
  228. {
  229.   VariantInit(reinterpret_cast<VARIANTARG *>(this));
  230.  
  231.   *this = System::VarArrayOf(values, valuesSize);
  232. }
  233.  
  234. __fastcall Variant::~Variant()
  235. {
  236.   System::VarClear(*this);
  237. }
  238.  
  239. Variant& __fastcall Variant::operator =(const Variant& rhs)
  240. {
  241.   System::VarCopyNoInd(*this, rhs);
  242.   return *this;
  243. }
  244.  
  245. Variant& __fastcall Variant::operator +=(const Variant&)
  246. {
  247.   asm
  248.   {
  249.     extrn   @System@@VarAdd$qqrv:near
  250.     call    @System@@VarAdd$qqrv
  251.   }
  252.   return *this;
  253. }
  254.  
  255. Variant& __fastcall Variant::operator -=(const Variant&)
  256. {
  257.   asm
  258.   {
  259.     extrn   @System@@VarSub$qqrv:near
  260.     call    @System@@VarSub$qqrv
  261.   }
  262.   return *this;
  263. }
  264.  
  265. Variant& __fastcall Variant::operator *=(const Variant&)
  266. {
  267.   asm
  268.   {
  269.     extrn   @System@@VarMul$qqrv:near
  270.     call    @System@@VarMul$qqrv
  271.   }
  272.   return *this;
  273. }
  274.  
  275. Variant& __fastcall Variant::operator /=(const Variant&)
  276. {
  277.   asm
  278.   {
  279.     extrn   @System@@VarRDiv$qqrv:near
  280.     call    @System@@VarRDiv$qqrv
  281.   }
  282.   return *this;
  283. }
  284.  
  285. Variant& __fastcall Variant::operator %=(const Variant&)
  286. {
  287.   asm
  288.   {
  289.     extrn   @System@@VarMod$qqrv:near
  290.     call    @System@@VarMod$qqrv
  291.   }
  292.   return *this;
  293. }
  294.  
  295. Variant& __fastcall Variant::operator &=(const Variant&)
  296. {
  297.   asm
  298.   {
  299.     extrn   @System@@VarAnd$qqrv:near
  300.     call    @System@@VarAnd$qqrv
  301.   }
  302.   return *this;
  303. }
  304.  
  305. Variant& __fastcall Variant::operator |=(const Variant&)
  306. {
  307.   asm
  308.   {
  309.     extrn   @System@@VarOr$qqrv:near
  310.     call    @System@@VarOr$qqrv
  311.   }
  312.   return *this;
  313. }
  314.  
  315. Variant& __fastcall Variant::operator ^=(const Variant&)
  316. {
  317.   asm
  318.   {
  319.     extrn   @System@@VarXor$qqrv:near
  320.     call    @System@@VarXor$qqrv
  321.   }
  322.   return *this;
  323. }
  324.  
  325. Variant& __fastcall Variant::operator <<=(const Variant&)
  326. {
  327.   asm
  328.   {
  329.     extrn   @System@@VarShl$qqrv:near
  330.     call    @System@@VarShl$qqrv
  331.   }
  332.   return *this;
  333. }
  334.  
  335. Variant& __fastcall Variant::operator >>=(const Variant&)
  336. {
  337.   asm
  338.   {
  339.     extrn   @System@@VarShr$qqrv:near
  340.     call    @System@@VarShr$qqrv
  341.   }
  342.   return *this;
  343. }
  344.  
  345. bool __fastcall Variant::operator ==(const Variant&) const
  346. {
  347.   asm
  348.   {
  349.     extrn   @System@@VarCmp$qqrv:near
  350.     call    @System@@VarCmp$qqrv
  351.     sete    al
  352.     and     eax, 1
  353.   }
  354. }
  355.  
  356. bool __fastcall Variant::operator !=(const Variant&) const
  357. {
  358.   asm
  359.   {
  360.     extrn   @System@@VarCmp$qqrv:near
  361.     call    @System@@VarCmp$qqrv
  362.     setne   al
  363.     and     eax, 1
  364.   }
  365. }
  366.  
  367. bool __fastcall Variant::operator <(const Variant&) const
  368. {
  369.   asm
  370.   {
  371.     extrn   @System@@VarCmp$qqrv:near
  372.     call    @System@@VarCmp$qqrv
  373.     setb    al
  374.     and     eax, 1
  375.   }
  376. }
  377.  
  378. bool __fastcall Variant::operator >(const Variant&) const
  379. {
  380.   asm
  381.   {
  382.     extrn   @System@@VarCmp$qqrv:near
  383.     call    @System@@VarCmp$qqrv
  384.     seta    al
  385.     and     eax, 1
  386.   }
  387. }
  388.  
  389. bool __fastcall Variant::operator <=(const Variant& rhs) const
  390. {
  391.   return !operator >(rhs);
  392. }
  393.  
  394. bool __fastcall Variant::operator >=(const Variant& rhs) const
  395. {
  396.   return !operator <(rhs);
  397. }
  398.  
  399. Variant __fastcall Variant::operator +(const Variant& rhs) const
  400. {
  401.   Variant tmp(*this);
  402.   Variant* ptmp = &tmp;
  403.   asm
  404.   {
  405.     extrn   @System@@VarAdd$qqrv:near
  406.     mov     eax, ptmp
  407.     mov     edx, rhs
  408.  
  409.     call    @System@@VarAdd$qqrv
  410.   }
  411.   return tmp;
  412. }
  413.  
  414. Variant __fastcall Variant::operator -(const Variant& rhs) const
  415. {
  416.   Variant tmp(*this);
  417.   Variant* ptmp = &tmp;
  418.   asm
  419.   {
  420.     extrn   @System@@VarSub$qqrv:near
  421.     mov     eax, ptmp
  422.     mov     edx, rhs
  423.     call    @System@@VarSub$qqrv
  424.   }
  425.   return tmp;
  426. }
  427.  
  428. Variant __fastcall Variant::operator *(const Variant& rhs) const
  429. {
  430.   Variant tmp(*this);
  431.   Variant* ptmp = &tmp;
  432.   asm
  433.   {
  434.     extrn   @System@@VarMul$qqrv:near
  435.     mov     eax, ptmp
  436.     mov     edx, rhs
  437.     call    @System@@VarMul$qqrv
  438.   }
  439.   return tmp;
  440. }
  441.  
  442. Variant __fastcall Variant::operator /(const Variant& rhs) const
  443. {
  444.   Variant tmp(*this);
  445.   Variant* ptmp = &tmp;
  446.   asm
  447.   {
  448.     extrn   @System@@VarRDiv$qqrv:near
  449.     mov     eax, ptmp
  450.     mov     edx, rhs
  451.     call    @System@@VarRDiv$qqrv
  452.   }
  453.   return tmp;
  454. }
  455.  
  456. Variant __fastcall Variant::operator %(const Variant& rhs) const
  457. {
  458.   Variant tmp(*this);
  459.   Variant* ptmp = &tmp;
  460.   asm
  461.   {
  462.     extrn   @System@@VarMod$qqrv:near
  463.     mov     eax, ptmp
  464.     mov     edx, rhs
  465.     call    @System@@VarMod$qqrv
  466.   }
  467.   return tmp;
  468. }
  469.  
  470. Variant __fastcall Variant::operator &(const Variant& rhs) const
  471. {
  472.   Variant tmp(*this);
  473.   Variant* ptmp = &tmp;
  474.   asm
  475.   {
  476.     extrn   @System@@VarAnd$qqrv:near
  477.     mov     eax, ptmp
  478.     mov     edx, rhs
  479.     call    @System@@VarAnd$qqrv
  480.   }
  481.   return tmp;
  482. }
  483.  
  484. Variant __fastcall Variant::operator |(const Variant& rhs) const
  485. {
  486.   Variant tmp(*this);
  487.   Variant* ptmp = &tmp;
  488.   asm
  489.   {
  490.     extrn   @System@@VarOr$qqrv:near
  491.     mov     eax, ptmp
  492.     mov     edx, rhs
  493.     call    @System@@VarOr$qqrv
  494.   }
  495.   return tmp;
  496. }
  497.  
  498. Variant __fastcall Variant::operator ^(const Variant& rhs) const
  499. {
  500.   Variant tmp(*this);
  501.   Variant* ptmp = &tmp;
  502.   asm
  503.   {
  504.     extrn   @System@@VarXor$qqrv:near
  505.     mov     eax, ptmp
  506.     mov     edx, rhs
  507.     call    @System@@VarXor$qqrv
  508.   }
  509.   return tmp;
  510. }
  511.  
  512. Variant __fastcall Variant::operator <<(const Variant& rhs) const
  513. {
  514.   Variant tmp(*this);
  515.   Variant* ptmp = &tmp;
  516.   asm
  517.   {
  518.     extrn   @System@@VarShl$qqrv:near
  519.     mov     eax, ptmp
  520.     mov     edx, rhs
  521.     call    @System@@VarShl$qqrv
  522.   }
  523.   return tmp;
  524. }
  525.  
  526. Variant __fastcall Variant::operator >>(const Variant& rhs) const
  527. {
  528.   Variant tmp(*this);
  529.   Variant* ptmp = &tmp;
  530.   asm
  531.   {
  532.     extrn   @System@@VarShr$qqrv:near
  533.     mov     eax, ptmp
  534.     mov     edx, rhs
  535.     call    @System@@VarShr$qqrv
  536.   }
  537.   return tmp;
  538. }
  539.  
  540. Variant __fastcall Variant::operator -() const
  541. {
  542.   Variant tmp(*this);
  543.   Variant* ptmp = &tmp;
  544.   asm
  545.   {
  546.     extrn   @System@@VarNeg$qqrv:near
  547.     mov     eax, ptmp
  548.     call    @System@@VarNeg$qqrv
  549.   }
  550.   return tmp;
  551. }
  552.  
  553. Variant __fastcall Variant::operator !() const
  554. {
  555.   Variant tmp(*this);
  556.   Variant* ptmp = &tmp;
  557.   asm
  558.   {
  559.     extrn   @System@@VarNot$qqrv:near
  560.     mov     eax, ptmp
  561.     call    @System@@VarNot$qqrv
  562.   }
  563.   return tmp;
  564. }
  565.  
  566. __fastcall Variant::operator short() const
  567. {
  568.   Variant tmp;
  569.   System::VarCast(tmp, *this, varSmallint);
  570.   return tmp.VSmallint;
  571. }
  572.  
  573. __fastcall Variant::operator int() const
  574. {
  575.   Variant tmp;
  576.   System::VarCast(tmp, *this, varInteger);
  577.   return tmp.VInteger;
  578. }
  579.  
  580. __fastcall Variant::operator float() const
  581. {
  582.   Variant tmp;
  583.   System::VarCast(tmp, *this, varSingle);
  584.   return tmp.VSingle;
  585. }
  586.  
  587. __fastcall Variant::operator double() const
  588. {
  589.   Variant tmp;
  590.   System::VarCast(tmp, *this, varDouble);
  591.   return tmp.VDouble;
  592. }
  593.  
  594. __fastcall Variant::operator Currency() const
  595. {
  596.   Variant tmp;
  597.   System::VarCast(tmp, *this, varCurrency);
  598.   return tmp.VCurrency;
  599. }
  600.  
  601. __fastcall Variant::operator TDateTime() const
  602. {
  603.   Variant tmp;
  604.   System::VarCast(tmp, *this, varDate);
  605.   return tmp.VDate;
  606. }
  607.  
  608. __fastcall Variant::operator bool() const
  609. {
  610.   Variant tmp;
  611.   System::VarCast(tmp, *this, varBoolean);
  612.   return (bool)tmp.VBoolean;
  613. }
  614.  
  615. __fastcall Variant::operator WordBool() const
  616. {
  617.   Variant tmp;
  618.   System::VarCast(tmp, *this, varBoolean);
  619.   return tmp.VBoolean;
  620. }
  621.  
  622. __fastcall Variant::operator Byte() const
  623. {
  624.   Variant tmp;
  625.   System::VarCast(tmp, *this, varByte);
  626.   return tmp.VByte;
  627. }
  628.  
  629. __fastcall Variant::operator AnsiString() const
  630. {
  631.   Variant tmp;
  632.   System::VarCast(tmp, *this, varString);
  633.   return AnsiString((AnsiString&)(tmp.VString));
  634. }
  635.  
  636. __fastcall Variant::operator Ole2::IDispatch*()
  637. {
  638.   Variant tmp;
  639.   System::VarCast(tmp, *this, varDispatch);
  640.   if (tmp.VDispatch)
  641.     tmp.VDispatch->AddRef();
  642.   return tmp.VDispatch;
  643. }
  644.  
  645. __fastcall Variant::operator Ole2::IUnknown*()
  646. {
  647.   Variant tmp;
  648.   System::VarCast(tmp, *this, varUnknown);
  649.   if (tmp.VUnknown)
  650.     tmp.VUnknown->AddRef();
  651.   return tmp.VUnknown;
  652. }
  653.  
  654. // by ref conversion operators
  655. __fastcall Variant::operator short*()
  656. {
  657.   if (VType == (varSmallint | varByRef))
  658.     return reinterpret_cast<short*>(VPointer);
  659.   else if (VType == varSmallint)
  660.     return &VSmallint;
  661.   else
  662.     throw new EVariantError(sOpShortPtr);
  663. }
  664.  
  665. __fastcall Variant::operator int*()
  666. {
  667.   if (VType == (varInteger | varByRef))
  668.     return reinterpret_cast<int*>(VPointer);
  669.   else if (VType == varInteger)
  670.     return &VInteger;
  671.   else
  672.     throw new EVariantError(sOpIntPtr);
  673. }
  674.  
  675. __fastcall Variant::operator float*()
  676. {
  677.   if (VType == (varSingle | varByRef))
  678.     return reinterpret_cast<float*>(VPointer);
  679.   else if (VType == varSingle)
  680.     return &VSingle;
  681.   else
  682.     throw new EVariantError(sOpFloatPtr);
  683. }
  684.  
  685. __fastcall Variant::operator double*()
  686. {
  687.   if (VType == (varDouble | varByRef))
  688.     return reinterpret_cast<double*>(VPointer);
  689.   else if (VType == varDouble)
  690.     return &VDouble;
  691.   else
  692.     throw new EVariantError(sOpDoublePtr);
  693. }
  694.  
  695. __fastcall Variant::operator Currency*()
  696. {
  697.   if (VType == (varCurrency | varByRef))
  698.     return reinterpret_cast<Currency*>(VPointer);
  699.   else if (VType == varCurrency)
  700.     return reinterpret_cast<Currency*>(&VCurrency);
  701.   else
  702.     throw new EVariantError(sOpCurrencyPtr);
  703. }
  704.  
  705. __fastcall Variant::operator TDateTime*()
  706. {
  707.   if (VType == (varDate | varByRef))
  708.     return reinterpret_cast<TDateTime*>(VPointer);
  709.   else if (VType == varDate)
  710.     return reinterpret_cast<TDateTime*>(&VDate);
  711.   else
  712.     throw new EVariantError(sOpTDateTimePtr);
  713. }
  714.  
  715. __fastcall Variant::operator WordBool*()
  716. {
  717.   if (VType == (varBoolean | varByRef))
  718.     return reinterpret_cast<WordBool*>(VPointer);
  719.   else
  720.     throw new EVariantError(sOpBoolPtr);
  721. }
  722.  
  723. __fastcall Variant::operator Byte*()
  724. {
  725.   if (VType == (varByte | varByRef))
  726.     return reinterpret_cast<Byte*>(VPointer);
  727.   else if (VType == varByte)
  728.     return &VByte;
  729.   else
  730.     throw new EVariantError(sOpBytePtr);
  731. }
  732.  
  733. __fastcall Variant::operator wchar_t**()
  734. {
  735.   if (VType == (varOleStr | varByRef))
  736.     return reinterpret_cast<wchar_t**>(VPointer);
  737.   else if (VType == varOleStr)
  738.     return &VOleStr;
  739.   else
  740.     throw new EVariantError(sOpWCharTPtr);
  741. }
  742.  
  743. void __fastcall Variant::SetError(const int err)
  744. {
  745.   Clear();
  746.   VType = varError;
  747.   VError = err;
  748. }
  749.  
  750. int __fastcall Variant::GetError() const
  751. {
  752.   Variant tmp;
  753.   System::VarCast(tmp, *this, varError);
  754.   return tmp.VError;
  755. }
  756.  
  757. Variant& __fastcall Variant::ChangeType(int varType)
  758. {
  759.   Variant tmp;
  760.   System::VarCast(tmp, *this, varType);
  761.   return operator =(tmp);
  762. }
  763.  
  764. Variant __fastcall Variant::AsType(int varType) const
  765. {
  766.   Variant tmp;
  767.   System::VarCast(tmp, *this, varType);
  768.   return tmp;
  769. }
  770.  
  771. void __fastcall Variant::Clear()
  772. {
  773.   System::VarClear(*this);
  774. }
  775.  
  776. int __fastcall Variant::Type() const
  777. {
  778.   return System::VarType(*this);
  779. }
  780.  
  781. bool __fastcall Variant::IsNull() const
  782. {
  783.   return System::VarIsNull(*this);
  784. }
  785.  
  786. bool __fastcall Variant::IsEmpty() const
  787. {
  788.   return System::VarIsEmpty(*this);
  789. }
  790.  
  791. bool __fastcall Variant::IsArray() const
  792. {
  793.   return System::VarIsArray(*this);
  794. }
  795.  
  796. int __fastcall Variant::ArrayDimCount() const
  797. {
  798.   return System::VarArrayDimCount(*this);
  799. }
  800.  
  801. int __fastcall Variant::ArrayLowBound(const int dim) const
  802. {
  803.   return System::VarArrayLowBound(*this, dim);
  804. }
  805.  
  806. int __fastcall Variant::ArrayHighBound(const int dim) const
  807. {
  808.   return System::VarArrayHighBound(*this, dim);
  809. }
  810.  
  811. void __fastcall Variant::ArrayRedim(int highBound)
  812. {
  813.   System::VarArrayRedim(*this, highBound);
  814. }
  815.  
  816. Pointer __fastcall Variant::ArrayLock()
  817. {
  818.   return System::VarArrayLock(*this);
  819. }
  820.  
  821. void    __fastcall Variant::ArrayUnlock()
  822. {
  823.   System::VarArrayUnlock(*this);
  824. }
  825.  
  826. Variant& __fastcall Variant::operator [](const int idx)
  827. {
  828.   if (!IsArray() || idx < ArrayLowBound() || idx > ArrayHighBound())
  829.     throw new EVariantError(sVarRangeArray);
  830.  
  831.   Variant* array((Variant*)ArrayLock());
  832.   Variant* v(array + idx);
  833.   ArrayUnlock();
  834.   return *v;
  835. }
  836.  
  837. Variant __fastcall Variant::GetElement(const int i1) const
  838. {
  839.   Variant tmp;
  840.   Variant* ptmp = &tmp;
  841.   asm {
  842.     extrn @System@@VarArrayGet$qr14System@Variantii:near
  843.     push i1
  844.     push 1
  845.     mov eax, this
  846.     push eax
  847.     mov eax, ptmp
  848.     push eax
  849.     call    @System@@VarArrayGet$qr14System@Variantii
  850.     add esp, 0x10
  851.   }
  852.   return tmp;
  853. }
  854.  
  855. Variant __fastcall Variant::GetElement(const int i1, const int i2) const
  856. {
  857.   Variant tmp;
  858.   Variant* ptmp = &tmp;
  859.   asm {
  860.     extrn @System@@VarArrayGet$qr14System@Variantii:near
  861.     push i2
  862.     push i1
  863.     push 2
  864.     mov eax, this
  865.     push eax
  866.     mov eax, ptmp
  867.     push eax
  868.     call    @System@@VarArrayGet$qr14System@Variantii
  869.     add esp, 0x14
  870.   }
  871.   return tmp;
  872. }
  873.  
  874. Variant __fastcall Variant::GetElement(const int i1, const int i2,
  875.   const int i3) const
  876. {
  877.   Variant tmp;
  878.   Variant* ptmp = &tmp;
  879.   asm {
  880.     extrn @System@@VarArrayGet$qr14System@Variantii:near
  881.     push i3
  882.     push i2
  883.     push i1
  884.     push 3
  885.     mov eax, this
  886.     push eax
  887.     mov eax, ptmp
  888.     push eax
  889.     call    @System@@VarArrayGet$qr14System@Variantii
  890.     add esp, 0x18
  891.   }
  892.   return tmp;
  893. }
  894.  
  895. Variant __fastcall Variant::GetElement(const int i1, const int i2,
  896.   const int i3, const int i4) const
  897. {
  898.   Variant tmp;
  899.   Variant* ptmp = &tmp;
  900.   asm {
  901.     extrn @System@@VarArrayGet$qr14System@Variantii:near
  902.     push i4
  903.     push i3
  904.     push i2
  905.     push i1
  906.     push 4
  907.     mov eax, this
  908.     push eax
  909.     mov eax, ptmp
  910.     push eax
  911.     call    @System@@VarArrayGet$qr14System@Variantii
  912.     add esp, 0x1C
  913.   }
  914.   return tmp;
  915. }
  916.  
  917. Variant __fastcall Variant::GetElement(const int i1, const int i2,
  918.   const int i3, const int i4, const int i5) const
  919. {
  920.   Variant tmp;
  921.   Variant* ptmp = &tmp;
  922.   asm {
  923.     extrn @System@@VarArrayGet$qr14System@Variantii:near
  924.     push i5
  925.     push i4
  926.     push i3
  927.     push i2
  928.     push i1
  929.     push 5
  930.     mov eax, this
  931.     push eax
  932.     mov eax, ptmp
  933.     push eax
  934.     call    @System@@VarArrayGet$qr14System@Variantii
  935.     add esp, 0x20
  936.   }
  937.   return tmp;
  938. }
  939.  
  940. void __fastcall Variant::PutElement(const Variant& data, const int i1)
  941. {
  942.   asm {
  943.     extrn   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii:near
  944.     push i1
  945.     push 1
  946.     mov eax, data
  947.     push eax
  948.     mov eax, this
  949.     push eax
  950.     call   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii
  951.     add esp, 0x10
  952.   }
  953. }
  954.  
  955. void __fastcall Variant::PutElement(const Variant& data, const int i1,
  956.   const int i2)
  957. {
  958.   asm {
  959.     extrn   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii:near
  960.     push i2
  961.     push i1
  962.     push 2
  963.     mov eax, data
  964.     push eax
  965.     mov eax, this
  966.     push eax
  967.     call   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii
  968.     add esp, 0x14
  969.   }
  970. }
  971.  
  972. void __fastcall Variant::PutElement(const Variant& data, const int i1,
  973.   const int i2, const int i3)
  974. {
  975.   asm {
  976.     extrn   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii:near
  977.     push i3
  978.     push i2
  979.     push i1
  980.     push 3
  981.     mov eax, data
  982.     push eax
  983.     mov eax, this
  984.     push eax
  985.     call   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii
  986.     add esp, 0x18
  987.   }
  988. }
  989.  
  990. void __fastcall Variant::PutElement(const Variant& data, const int i1,
  991.   const int i2, const int i3, const int i4)
  992. {
  993.   asm {
  994.     extrn   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii:near
  995.     push i4
  996.     push i3
  997.     push i2
  998.     push i1
  999.     push 4
  1000.     mov eax, data
  1001.     push eax
  1002.     mov eax, this
  1003.     push eax
  1004.     call   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii
  1005.     add esp, 0x1C
  1006.   }
  1007. }
  1008.  
  1009. void __fastcall Variant::PutElement(const Variant& data, const int i1,
  1010.   const int i2, const int i3, const int i4, const int i5)
  1011. {
  1012.   asm {
  1013.     extrn   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii:near
  1014.     push i5
  1015.     push i4
  1016.     push i3
  1017.     push i2
  1018.     push i1
  1019.     push 5
  1020.     mov eax, data
  1021.     push eax
  1022.     mov eax, this
  1023.     push eax
  1024.     call   @System@@VarArrayPut$qr14System@Variantrx14System@Variantii
  1025.     add esp, 0x20
  1026.   }
  1027. }
  1028.  
  1029. Variant __fastcall Variant::Exec(AutoCmd& cmd, Integer) const
  1030. {
  1031.   //Result
  1032.   Variant tmp;
  1033.   Variant* ptmp = 0;
  1034.  
  1035.   if (cmd.RequestResult())
  1036.     ptmp = &tmp;
  1037.  
  1038.   //construct a call descriptor
  1039.   TCallDesc callDesc;
  1040.   TCallDesc* pcallDesc = &callDesc;
  1041.  
  1042.   // set calltype, argcount, named arg count
  1043.   callDesc.CallType = cmd.GetCallType();
  1044.   callDesc.ArgCount = cmd.GetArgCount();
  1045.   callDesc.NamedArgCount = cmd.GetNamedArgCount();
  1046.  
  1047.   // fill in arg types for named args
  1048.   for (Byte i = 0; i < callDesc.NamedArgCount; i++)
  1049.   {
  1050.     int argType = cmd.GetNamedArgType(i);
  1051.     if (argType == varString)
  1052.       callDesc.ArgTypes[i] = varStrArg;
  1053.     else if (argType == (varString | varByRef))
  1054.       callDesc.ArgTypes[i] = varStrArg + 128;
  1055.     else
  1056.     {
  1057.       callDesc.ArgTypes[i] = (Byte)(argType & varTypeMask);
  1058.       callDesc.ArgTypes[i] += (Byte)((argType & varByRef)? 128: 0);
  1059.     }
  1060.   }
  1061.  
  1062.   // fill in arg types for un-named args
  1063.   for (Byte i = callDesc.NamedArgCount; i < callDesc.ArgCount; i++)
  1064.   {
  1065.     int argType = cmd.GetArgType((Byte)(i-callDesc.NamedArgCount));
  1066.     if (argType == varString)
  1067.       callDesc.ArgTypes[i] = varStrArg;
  1068.     else if (argType == (varString | varByRef))
  1069.       callDesc.ArgTypes[i] = varStrArg + 128;
  1070.     else
  1071.     {
  1072.       callDesc.ArgTypes[i] = (Byte)(argType & varTypeMask);
  1073.       callDesc.ArgTypes[i] += (Byte)((argType & varByRef)? 128: 0);
  1074.     }
  1075.   }
  1076.  
  1077.   // get ptr that points after all argtypes
  1078.   char* p = (char*) &callDesc.ArgTypes[callDesc.ArgCount];
  1079.  
  1080.   // fill in the name of the cmd
  1081.   p = stpcpy(p, (char*)cmd.GetName().c_str());
  1082.  
  1083.   // fill in names of named args
  1084.   for (Byte i = 0; i < callDesc.NamedArgCount; i++)
  1085.     p = stpcpy(p+1, (char*)cmd.GetNamedParmName(i).c_str());
  1086.  
  1087.   // fill an array of values/addresses of named args (makes asm easier)
  1088.   void* namedParms[MaxDispArgs*2];
  1089.   void* namedParmsPtr = &namedParms;
  1090.   Byte namedCursor = 0;
  1091.   for (Byte i = 0; i < callDesc.NamedArgCount; i++)
  1092.   {
  1093.     Variant* v = & cmd.GetNamedParm(i);
  1094.     int argType = cmd.GetNamedArgType(i) & varTypeMask;
  1095.     bool byRef = cmd.GetNamedArgType(i) & varByRef;
  1096.     if (!byRef)
  1097.     {
  1098.       switch (argType)
  1099.       {
  1100.         case varString:
  1101.           namedParms[namedCursor++] = cmd.GetNamedStringArg(i).c_str();
  1102.           break;
  1103.         case varDouble:
  1104.         case varDate:
  1105.         case varCurrency:
  1106.           namedParms[namedCursor++] = reinterpret_cast<void*>(*((&v->VInteger) + 1)); //half
  1107.           namedParms[namedCursor++] = reinterpret_cast<void*>(v->VInteger);  // other half
  1108.           break;
  1109.         case varSingle:
  1110.         case varDispatch:
  1111.         case varInteger:
  1112.         case varBoolean:
  1113.         case varUnknown:
  1114.           namedParms[namedCursor++] = reinterpret_cast<void*>(v->VInteger);  // pick 1 (union)
  1115.           break;
  1116.         case varSmallint:
  1117.           namedParms[namedCursor++] = reinterpret_cast<void*>((int)v->VSmallint);
  1118.           break;
  1119.         case varByte:
  1120.           namedParms[namedCursor++] = reinterpret_cast<void*>((int)v->VByte);
  1121.           break;
  1122.         case varVariant:
  1123.           namedParms[namedCursor++] = v;
  1124.           break;
  1125.       }
  1126.     }
  1127.     else // byRef
  1128.     {
  1129.       if (argType == varString)
  1130.         namedParms[namedCursor++] = cmd.GetNamedStringPtr(i);
  1131.       else if (argType == varVariant)
  1132.         namedParms[namedCursor++] = v;
  1133.       else
  1134.         namedParms[namedCursor++] = v->VPointer;
  1135.     }
  1136.   }
  1137.   // fill an array of values/addresses of un-named args (makes asm easier)
  1138.   void* parms[MaxDispArgs*2];
  1139.   void* parmsPtr = &parms;
  1140.   Byte cursor = 0;
  1141.   for (Byte i = 0; i < callDesc.ArgCount - callDesc.NamedArgCount; i++)
  1142.   {
  1143.     Variant* v = & cmd.GetParm(i);
  1144.     int argType = cmd.GetArgType(i) & varTypeMask;
  1145.     bool byRef = cmd.GetArgType(i) & varByRef;
  1146.     if (!byRef)
  1147.     {
  1148.       switch (argType)
  1149.       {
  1150.         case varString:
  1151.           parms[cursor++] = cmd.GetStringArg(i).c_str();
  1152.           break;
  1153.         case varDouble:
  1154.         case varDate:
  1155.         case varCurrency:
  1156.           parms[cursor++] = reinterpret_cast<void*>(*((&v->VInteger) + 1)); //half
  1157.           parms[cursor++] = reinterpret_cast<void*>(v->VInteger);  // other half
  1158.           break;
  1159.         case varSingle:
  1160.         case varDispatch:
  1161.         case varInteger:
  1162.         case varBoolean:
  1163.         case varUnknown:
  1164.           parms[cursor++] = reinterpret_cast<void*>(v->VInteger);  // pick 1 (union)
  1165.           break;
  1166.         case varSmallint:
  1167.           parms[cursor++] = reinterpret_cast<void*>((int)v->VSmallint);
  1168.           break;
  1169.         case varByte:
  1170.           parms[cursor++] = reinterpret_cast<void*>((int)v->VByte);
  1171.           break;
  1172.         case varVariant:
  1173.           parms[cursor++] = v;
  1174.           break;
  1175.       }
  1176.     }
  1177.     else // byRef
  1178.     {
  1179.       if (argType == varString)
  1180.         parms[cursor++] = cmd.GetStringPtr(i);
  1181.       else if (argType == varVariant)
  1182.         parms[cursor++] = v;
  1183.       else
  1184.         parms[cursor++] = v->VPointer;
  1185.     }
  1186.   }
  1187.   asm
  1188.   {
  1189.     extrn   @System@@DispInvoke$qv:near
  1190.     xor     edx, edx
  1191.     mov     dl, cursor
  1192.     dec     edx
  1193.     imul    edx, 4
  1194.     add     edx, parmsPtr
  1195.     mov     cl, cursor
  1196. @@0:
  1197.     dec     cl
  1198.     test    cl,  cl
  1199.     jl      @@1
  1200.     mov     eax, [edx]
  1201.     push    eax
  1202.     sub     edx, 4
  1203.     jmp     @@0
  1204.  
  1205. @@1:
  1206.     xor     edx, edx
  1207.     mov     dl, namedCursor
  1208.     dec     edx
  1209.     imul    edx, 4
  1210.     add     edx, namedParmsPtr
  1211.     mov     cl, namedCursor
  1212. @@2:
  1213.     dec     cl
  1214.     test    cl,  cl
  1215.     jl      @@3
  1216.     mov     eax, [edx]
  1217.     push    eax
  1218.     sub     edx, 4
  1219.     jmp     @@2
  1220. @@3:
  1221.  
  1222.     push    pcallDesc
  1223.     push    this
  1224.     push    ptmp
  1225.  
  1226.     call    @System@@DispInvoke$qv
  1227.  
  1228.     xor     ecx, ecx
  1229.     mov     cl, cursor
  1230.     add     cl, namedCursor
  1231.     imul    ecx, 4
  1232.     add     ecx, 12
  1233.     add     esp, ecx
  1234.   }
  1235.  
  1236.   // if no result is returned, return a true
  1237.   if (!cmd.RequestResult())
  1238.     tmp = true;
  1239.  
  1240.   return tmp;
  1241. }
  1242.  
  1243. // alternate syntax automation stuff
  1244. void Variant::OleProcedure(const String& name, Variant& v0,
  1245.       Variant& v1, Variant& v2, Variant& v3,
  1246.       Variant& v4, Variant& v5, Variant& v6,
  1247.       Variant& v7, Variant& v8, Variant& v9) const
  1248. {
  1249.   Procedure p(name);
  1250.  
  1251.   if (v0.Type() != varEmpty)
  1252.   {
  1253.     p << v0;
  1254.     if (v1.Type() != varEmpty)
  1255.     {
  1256.       p << v1;
  1257.       if (v2.Type() != varEmpty)
  1258.       {
  1259.         p << v2;
  1260.         if (v3.Type() != varEmpty)
  1261.         {
  1262.           p << v3;
  1263.           if (v4.Type() != varEmpty)
  1264.           {
  1265.             p << v4;
  1266.             if (v5.Type() != varEmpty)
  1267.             {
  1268.               p << v5;
  1269.               if (v6.Type() != varEmpty)
  1270.               {
  1271.                 p << v6;
  1272.                 if (v7.Type() != varEmpty)
  1273.                 {
  1274.                   p << v7;
  1275.                   if (v8.Type() != varEmpty)
  1276.                   {
  1277.                     p << v8;
  1278.                     if (v9.Type() != varEmpty)
  1279.                       p << v9;
  1280.                   }
  1281.                 }
  1282.               }
  1283.             }
  1284.           }
  1285.         }
  1286.       }
  1287.     }
  1288.   }
  1289.   Exec(p);
  1290. }
  1291.  
  1292. Variant Variant::OleFunction(const String& name, Variant& v0,
  1293.       Variant& v1, Variant& v2, Variant& v3,
  1294.       Variant& v4, Variant& v5, Variant& v6,
  1295.       Variant& v7, Variant& v8, Variant& v9) const
  1296. {
  1297.   Function p(name);
  1298.  
  1299.   if (v0.Type() != varEmpty)
  1300.   {
  1301.     p << v0;
  1302.     if (v1.Type() != varEmpty)
  1303.     {
  1304.       p << v1;
  1305.       if (v2.Type() != varEmpty)
  1306.       {
  1307.         p << v2;
  1308.         if (v3.Type() != varEmpty)
  1309.         {
  1310.           p << v3;
  1311.           if (v4.Type() != varEmpty)
  1312.           {
  1313.             p << v4;
  1314.             if (v5.Type() != varEmpty)
  1315.             {
  1316.               p << v5;
  1317.               if (v6.Type() != varEmpty)
  1318.               {
  1319.                 p << v6;
  1320.                 if (v7.Type() != varEmpty)
  1321.                 {
  1322.                   p << v7;
  1323.                   if (v8.Type() != varEmpty)
  1324.                   {
  1325.                     p << v8;
  1326.                     if (v9.Type() != varEmpty)
  1327.                       p << v9;
  1328.                   }
  1329.                 }
  1330.               }
  1331.             }
  1332.           }
  1333.         }
  1334.       }
  1335.     }
  1336.   }
  1337.   return Exec(p);
  1338. }
  1339.  
  1340. Variant Variant::OlePropertyGet(const String& name, Variant& v0,
  1341.       Variant& v1, Variant& v2, Variant& v3,
  1342.       Variant& v4, Variant& v5, Variant& v6,
  1343.       Variant& v7, Variant& v8, Variant& v9) const
  1344. {
  1345.   PropertyGet p(name);
  1346.  
  1347.   if (v0.Type() != varEmpty)
  1348.   {
  1349.     p << v0;
  1350.     if (v1.Type() != varEmpty)
  1351.     {
  1352.       p << v1;
  1353.       if (v2.Type() != varEmpty)
  1354.       {
  1355.         p << v2;
  1356.         if (v3.Type() != varEmpty)
  1357.         {
  1358.           p << v3;
  1359.           if (v4.Type() != varEmpty)
  1360.           {
  1361.             p << v4;
  1362.             if (v5.Type() != varEmpty)
  1363.             {
  1364.               p << v5;
  1365.               if (v6.Type() != varEmpty)
  1366.               {
  1367.                 p << v6;
  1368.                 if (v7.Type() != varEmpty)
  1369.                 {
  1370.                   p << v7;
  1371.                   if (v8.Type() != varEmpty)
  1372.                   {
  1373.                     p << v8;
  1374.                     if (v9.Type() != varEmpty)
  1375.                       p << v9;
  1376.                   }
  1377.                 }
  1378.               }
  1379.             }
  1380.           }
  1381.         }
  1382.       }
  1383.     }
  1384.   }
  1385.   return Exec(p);
  1386. }
  1387.  
  1388. void Variant::OlePropertySet(const String& name, Variant& v0,
  1389.       Variant& v1, Variant& v2, Variant& v3,
  1390.       Variant& v4, Variant& v5, Variant& v6,
  1391.       Variant& v7, Variant& v8, Variant& v9) const
  1392. {
  1393.   PropertySet p(name);
  1394.  
  1395.   if (v0.Type() != varEmpty)
  1396.   {
  1397.     p << v0;
  1398.     if (v1.Type() != varEmpty)
  1399.     {
  1400.       p << v1;
  1401.       if (v2.Type() != varEmpty)
  1402.       {
  1403.         p << v2;
  1404.         if (v3.Type() != varEmpty)
  1405.         {
  1406.           p << v3;
  1407.           if (v4.Type() != varEmpty)
  1408.           {
  1409.             p << v4;
  1410.             if (v5.Type() != varEmpty)
  1411.             {
  1412.               p << v5;
  1413.               if (v6.Type() != varEmpty)
  1414.               {
  1415.                 p << v6;
  1416.                 if (v7.Type() != varEmpty)
  1417.                 {
  1418.                   p << v7;
  1419.                   if (v8.Type() != varEmpty)
  1420.                   {
  1421.                     p << v8;
  1422.                     if (v9.Type() != varEmpty)
  1423.                       p << v9;
  1424.                   }
  1425.                 }
  1426.               }
  1427.             }
  1428.           }
  1429.         }
  1430.       }
  1431.     }
  1432.   }
  1433.   Exec(p);
  1434. }
  1435. // end of alternate syntax automation stuff
  1436.  
  1437. ostream& operator <<(ostream& os, const Variant& arg)
  1438. {
  1439.   switch (arg.VType)
  1440.   {
  1441.     case varEmpty:
  1442.       os << "varEmpty";
  1443.       break;
  1444.     case varNull:
  1445.       os << "varNull";
  1446.       break;
  1447.     case varSmallint:
  1448.       os << "varSmallint: " << arg.VSmallint;
  1449.       break;
  1450.     case varInteger:
  1451.       os << "varInteger: " << arg.VInteger;
  1452.       break;
  1453.     case varSingle:
  1454.       os << "varSingle: " << arg.VSingle;
  1455.       break;
  1456.     case varDouble:
  1457.       os << "varDouble: " << arg.VDouble;
  1458.       break;
  1459.     case varCurrency:
  1460.       os << "varCurrency: " << arg.VCurrency;
  1461.       break;
  1462.     case varDate:
  1463.       os << "varDate: " << arg.VDate;
  1464.       break;
  1465.     case varOleStr:
  1466.       os << "varOleStr: " << AnsiString(arg.VOleStr);
  1467.       break;
  1468.     case varDispatch:
  1469.       os << "varDispatch: " << static_cast<void*>(arg.VDispatch);
  1470.       break;
  1471.     case varError:
  1472.       os << "varError: " << arg.VError;
  1473.       break;
  1474.     case varBoolean:
  1475.       os << "varBoolean: " << arg.operator bool();
  1476.       break;
  1477.     case varUnknown:
  1478.       os << "varUnknown: " << static_cast<void*>(arg.VUnknown);
  1479.       break;
  1480.     case varByte:
  1481.       os << "varByte: " << arg.VByte;
  1482.       break;
  1483.     case varString:
  1484.       os << "varString: " << arg.operator AnsiString();
  1485.       break;
  1486.     case varArray:
  1487.       os << "varArray: " << static_cast<void*>(arg.VArray);
  1488.       break;
  1489.     case varSmallint | varByRef:
  1490.       os << "varSmallint | varByRef: " << arg.VPointer;
  1491.       break;
  1492.     case varInteger | varByRef:
  1493.       os << "varInteger | varByRef: " << arg.VPointer;
  1494.       break;
  1495.     case varSingle | varByRef:
  1496.       os << "varSingle | varByRef: " << arg.VPointer;
  1497.       break;
  1498.     case varDouble | varByRef:
  1499.       os << "varDouble | varByRef: " << arg.VPointer;
  1500.       break;
  1501.     case varCurrency | varByRef:
  1502.       os << "varCurrency | varByRef: " << arg.VPointer;
  1503.       break;
  1504.     case varDate | varByRef:
  1505.       os << "varDate | varByRef: " << arg.VPointer;
  1506.       break;
  1507.     case varOleStr | varByRef:
  1508.       os << "varOleStr | varByRef: " << arg.VPointer;
  1509.       break;
  1510.     case varDispatch | varByRef:
  1511.       os << "varDispatch | varByRef: " << arg.VPointer;
  1512.       break;
  1513.     case varError | varByRef:
  1514.       os << "varError | varByRef: " << arg.VPointer;
  1515.       break;
  1516.     case varBoolean | varByRef:
  1517.       os << "varBoolean | varByRef: " << arg.VPointer;
  1518.       break;
  1519.     case varUnknown | varByRef:
  1520.       os << "varUnknown | varByRef: " << arg.VPointer;
  1521.       break;
  1522.     case varByte | varByRef:
  1523.       os << "varByte | varByRef: " << arg.VPointer;
  1524.       break;
  1525.     case varString | varByRef:
  1526.       os << "varString | varByRef: " << arg.VPointer;
  1527.       break;
  1528.     case varArray | varByRef:
  1529.       os << "varArray | varByRef: " << arg.VPointer;
  1530.       break;
  1531.   }
  1532.   return os;
  1533. }
  1534.  
  1535. AutoCmd::AutoCmd(const AutoCmd& src): Name(src.Name), Parms(src.Parms),
  1536.   ParmTypes(src.ParmTypes), NamedParms(src.NamedParms),
  1537.   NamedParmTypes(src.NamedParmTypes), NamedParmNames(src.NamedParmNames)
  1538. {
  1539.   for (int i = 0; i < MaxDispArgs; i++)
  1540.   {
  1541.     StringArgs[i] = src.StringArgs[i];
  1542.     StringPtrs[i] = src.StringPtrs[i];
  1543.     NamedStringArgs[i] = NamedStringArgs[i];
  1544.     NamedStringPtrs[i] = NamedStringPtrs[i];
  1545.   }
  1546. }
  1547.  
  1548. AutoCmd& AutoCmd::SetName(const String& name)
  1549. {
  1550.   Name = name;
  1551.   return *this;
  1552. }
  1553.  
  1554. AutoCmd& AutoCmd::Clear()
  1555. {
  1556.   ClearName();
  1557.   ClearArgs();
  1558.   return *this;
  1559. }
  1560.  
  1561. AutoCmd& AutoCmd::ClearName()
  1562. {
  1563.   SetName("");
  1564.   return *this;
  1565. }
  1566.  
  1567. AutoCmd& AutoCmd::ClearArgs()
  1568. {
  1569.   Parms.Clear();
  1570.   ParmTypes.Clear();
  1571.  
  1572.   NamedParms.Clear();
  1573.   NamedParmTypes.Clear();
  1574.   NamedParmNames.Clear();
  1575.  
  1576.   return *this;
  1577. }
  1578.  
  1579. int AutoCmd::GetArgType(const Byte idx) const
  1580. {
  1581.   if (ParmTypes.IsEmpty() || ParmTypes.ArrayHighBound() < idx)
  1582.     throw new EVariantError(sAcGatRange);
  1583.   return ParmTypes.GetElement(idx);
  1584. }
  1585.  
  1586. int AutoCmd::GetNamedArgType(const Byte idx) const
  1587. {
  1588.   if (NamedParmTypes.IsEmpty() || NamedParmTypes.ArrayHighBound() < idx)
  1589.     throw new EVariantError(sAcGnatRange);
  1590.   return NamedParmTypes.GetElement(idx);
  1591. }
  1592.  
  1593. Byte AutoCmd::GetArgCount() const
  1594. {
  1595.   int count = GetNamedArgCount();
  1596.   if (!Parms.IsEmpty())
  1597.     count += Parms.ArrayHighBound() + 1;
  1598.   return (Byte) count;
  1599. }
  1600.  
  1601. Byte AutoCmd::GetNamedArgCount() const
  1602. {
  1603.   int count = 0;
  1604.   if (!NamedParms.IsEmpty())
  1605.     count += NamedParms.ArrayHighBound() + 1;
  1606.   return (Byte)count;
  1607. }
  1608.  
  1609. Variant& AutoCmd::GetParm(const Byte idx)
  1610. {
  1611.   if (Parms.IsEmpty() || Parms.ArrayHighBound() < idx)
  1612.     throw new EVariantError(sAcGpRange);
  1613.   return Parms[idx];
  1614. }
  1615.  
  1616. Variant& AutoCmd::GetNamedParm(const Byte idx)
  1617. {
  1618.   if (NamedParms.IsEmpty() || NamedParms.ArrayHighBound() < idx)
  1619.     throw new EVariantError(sAcGnpRange);
  1620.   return NamedParms[idx];
  1621. }
  1622.  
  1623. String AutoCmd::GetNamedParmName(const Byte idx) const
  1624. {
  1625.   if (NamedParms.IsEmpty() || NamedParms.ArrayHighBound() < idx)
  1626.     throw new EVariantError(sAcGnpnRange);
  1627.   return NamedParmNames.GetElement(idx);
  1628. }
  1629.  
  1630. void AutoCmd::AddElement()
  1631. {
  1632.   if (Parms.IsEmpty())
  1633.   {
  1634.     Parms = Variant(OPENARRAY(int, (0, 0)), varVariant);
  1635.     ParmTypes = Variant(OPENARRAY(int, (0, 0)), varInteger);
  1636.   }
  1637.   else
  1638.   {
  1639.     Parms.ArrayRedim(Parms.ArrayHighBound()+1);
  1640.     ParmTypes.ArrayRedim(ParmTypes.ArrayHighBound()+1);
  1641.   }
  1642. }
  1643.  
  1644. AutoCmd& AutoCmd::operator <<(const Variant& v)
  1645. {
  1646.   AddElement();
  1647.   Parms.PutElement(v, Parms.ArrayHighBound());
  1648.   ParmTypes.PutElement(varVariant, ParmTypes.ArrayHighBound());
  1649.   return *this;
  1650. }
  1651.  
  1652. AutoCmd& AutoCmd::operator <<(const short arg)
  1653. {
  1654.   AddElement();
  1655.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1656.   ParmTypes.PutElement(varSmallint, ParmTypes.ArrayHighBound());
  1657.   return *this;
  1658. }
  1659.  
  1660. AutoCmd& AutoCmd::operator <<(const int arg)
  1661. {
  1662.   AddElement();
  1663.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1664.   ParmTypes.PutElement(varInteger, ParmTypes.ArrayHighBound());
  1665.   return *this;
  1666. }
  1667.  
  1668. AutoCmd& AutoCmd::operator <<(const float arg)
  1669. {
  1670.   AddElement();
  1671.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1672.   ParmTypes.PutElement(varSingle, ParmTypes.ArrayHighBound());
  1673.   return *this;
  1674. }
  1675.  
  1676. AutoCmd& AutoCmd::operator <<(const double arg)
  1677. {
  1678.   AddElement();
  1679.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1680.   ParmTypes.PutElement(varDouble, ParmTypes.ArrayHighBound());
  1681.   return *this;
  1682. }
  1683.  
  1684. AutoCmd& AutoCmd::operator <<(const Currency arg)
  1685. {
  1686.   AddElement();
  1687.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1688.   ParmTypes.PutElement(varCurrency, ParmTypes.ArrayHighBound());
  1689.   return *this;
  1690. }
  1691.  
  1692. AutoCmd& AutoCmd::operator <<(const TDateTime arg)
  1693. {
  1694.   AddElement();
  1695.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1696.   ParmTypes.PutElement(varDate, ParmTypes.ArrayHighBound());
  1697.   return *this;
  1698. }
  1699.  
  1700. AutoCmd& AutoCmd::operator <<(const bool arg)
  1701. {
  1702.   AddElement();
  1703.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1704.   ParmTypes.PutElement(varBoolean, ParmTypes.ArrayHighBound());
  1705.   return *this;
  1706. }
  1707.  
  1708. AutoCmd& AutoCmd::operator <<(const WordBool arg)
  1709. {
  1710.   AddElement();
  1711.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1712.   ParmTypes.PutElement(varBoolean, ParmTypes.ArrayHighBound());
  1713.   return *this;
  1714. }
  1715.  
  1716. AutoCmd& AutoCmd::operator <<(const Byte arg)
  1717. {
  1718.   AddElement();
  1719.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1720.   ParmTypes.PutElement(varByte, ParmTypes.ArrayHighBound());
  1721.   return *this;
  1722. }
  1723.  
  1724. AutoCmd& AutoCmd::operator <<(const AnsiString& arg)
  1725. {
  1726.   AddElement();
  1727.   int dummy = 0;
  1728.   Parms.PutElement(dummy, Parms.ArrayHighBound());
  1729.   ParmTypes.PutElement(varString, ParmTypes.ArrayHighBound());
  1730.   StringArgs[Parms.ArrayHighBound()] = arg;
  1731.   return *this;
  1732. }
  1733.  
  1734. AutoCmd& AutoCmd::operator <<(Ole2::IDispatch* const arg)
  1735. {
  1736.   AddElement();
  1737.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1738.   ParmTypes.PutElement(varDispatch, ParmTypes.ArrayHighBound());
  1739.   return *this;
  1740. }
  1741.  
  1742. AutoCmd& AutoCmd::operator <<(Ole2::IUnknown* const arg)
  1743. {
  1744.   AddElement();
  1745.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1746.   ParmTypes.PutElement(varUnknown, ParmTypes.ArrayHighBound());
  1747.   return *this;
  1748. }
  1749.  
  1750. AutoCmd& AutoCmd::operator <<(Variant* arg)
  1751. {
  1752.   Variant v;
  1753.   v.VType = varVariant | varByRef;
  1754.   v.VPointer = arg;
  1755.   AddElement();
  1756.   Parms.PutElement(v, Parms.ArrayHighBound());
  1757.   ParmTypes.PutElement(varVariant | varByRef, ParmTypes.ArrayHighBound());
  1758.   return *this;
  1759. }
  1760.  
  1761. AutoCmd& AutoCmd::operator <<(short* arg)
  1762. {
  1763.   AddElement();
  1764.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1765.   ParmTypes.PutElement(varSmallint | varByRef, ParmTypes.ArrayHighBound());
  1766.   return *this;
  1767. }
  1768.  
  1769. AutoCmd& AutoCmd::operator <<(int* arg)
  1770. {
  1771.   AddElement();
  1772.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1773.   ParmTypes.PutElement(varInteger | varByRef, ParmTypes.ArrayHighBound());
  1774.   return *this;
  1775. }
  1776.  
  1777. AutoCmd& AutoCmd::operator <<(float* arg)
  1778. {
  1779.   AddElement();
  1780.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1781.   ParmTypes.PutElement(varSingle | varByRef, ParmTypes.ArrayHighBound());
  1782.   return *this;
  1783. }
  1784.  
  1785. AutoCmd& AutoCmd::operator <<(double* arg)
  1786. {
  1787.   AddElement();
  1788.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1789.   ParmTypes.PutElement(varDouble | varByRef, ParmTypes.ArrayHighBound());
  1790.   return *this;
  1791. }
  1792.  
  1793. AutoCmd& AutoCmd::operator <<(Currency* arg)
  1794. {
  1795.   AddElement();
  1796.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1797.   ParmTypes.PutElement(varCurrency | varByRef, ParmTypes.ArrayHighBound());
  1798.   return *this;
  1799. }
  1800.  
  1801. AutoCmd& AutoCmd::operator <<(TDateTime* arg)
  1802. {
  1803.   AddElement();
  1804.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1805.   ParmTypes.PutElement(varDate | varByRef, ParmTypes.ArrayHighBound());
  1806.   return *this;
  1807. }
  1808.  
  1809. AutoCmd& AutoCmd::operator <<(WordBool* arg)
  1810. {
  1811.   AddElement();
  1812.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1813.   ParmTypes.PutElement(varBoolean | varByRef, ParmTypes.ArrayHighBound());
  1814.   return *this;
  1815. }
  1816.  
  1817. AutoCmd& AutoCmd::operator <<(Byte* arg)
  1818. {
  1819.   AddElement();
  1820.   Parms.PutElement(arg, Parms.ArrayHighBound());
  1821.   ParmTypes.PutElement(varByte | varByRef, ParmTypes.ArrayHighBound());
  1822.   return *this;
  1823. }
  1824.  
  1825. AutoCmd& AutoCmd::operator <<(AnsiString* arg)
  1826. {
  1827.   AddElement();
  1828.   int dummy = 0;
  1829.   Parms.PutElement(dummy, Parms.ArrayHighBound());
  1830.   ParmTypes.PutElement(varString | varByRef, ParmTypes.ArrayHighBound());
  1831.   StringPtrs[Parms.ArrayHighBound()] = arg;
  1832.   return *this;
  1833. }
  1834.  
  1835. AutoCmd& AutoCmd::operator <<(const NamedParm& np)
  1836. {
  1837.   if (NamedParms.IsEmpty())
  1838.   {
  1839.     NamedParms     = Variant(OPENARRAY(int, (0, 0)), varVariant);
  1840.     NamedParmTypes = Variant(OPENARRAY(int, (0, 0)), varInteger);
  1841.     NamedParmNames = Variant(OPENARRAY(int, (0, 0)), varVariant);
  1842.   }
  1843.   else
  1844.   {
  1845.     NamedParms.ArrayRedim(NamedParms.ArrayHighBound()+1);
  1846.     NamedParmTypes.ArrayRedim(NamedParmTypes.ArrayHighBound()+1);
  1847.     NamedParmNames.ArrayRedim(NamedParmNames.ArrayHighBound()+1);
  1848.   }
  1849.  
  1850.   NamedParmNames.PutElement(np.GetParmName(), NamedParmNames.ArrayHighBound());
  1851.   int parmType = np.GetType();
  1852.   NamedParmTypes.PutElement(parmType, NamedParmTypes.ArrayHighBound());
  1853.   if (parmType == varString)
  1854.   {
  1855.     int dummy = 0;
  1856.     NamedParms.PutElement(dummy, NamedParms.ArrayHighBound());
  1857.     NamedStringArgs[NamedParms.ArrayHighBound()] = np.GetStringParm();
  1858.   }
  1859.   else if (parmType == (varString | varByRef))
  1860.   {
  1861.     int dummy = 0;
  1862.     NamedParms.PutElement(dummy, NamedParms.ArrayHighBound());
  1863.     NamedStringPtrs[NamedParms.ArrayHighBound()] = np.GetStringPtr();
  1864.   }
  1865.   else
  1866.     NamedParms.PutElement(np.GetParm(), NamedParms.ArrayHighBound());
  1867.  
  1868.   return *this;
  1869. }
  1870.  
  1871. NamedParm::NamedParm(const String& name, Variant* arg): Name(name),
  1872.   Type(varVariant | varByRef)
  1873. {
  1874.   Variant v;
  1875.   v.VType = varVariant | varByRef;
  1876.   v.VPointer = arg;
  1877.   Parm = v;
  1878. }
  1879.  
  1880. Byte Procedure::GetCallType() const
  1881. {
  1882.   return DISPATCH_METHOD;
  1883. }
  1884.  
  1885. Byte Function::GetCallType() const
  1886. {
  1887.   return DISPATCH_METHOD;
  1888. }
  1889.  
  1890. Byte PropertySet::GetCallType() const
  1891. {
  1892.   return DISPATCH_PROPERTYPUT;
  1893. }
  1894.  
  1895. Byte PropertyGet::GetCallType() const
  1896. {
  1897.   return DISPATCH_PROPERTYGET;
  1898. }
  1899.  
  1900. //---------------------------------------------------------------------
  1901. TDateTime __fastcall TDateTime::CurrentDate()
  1902. {
  1903.   return Sysutils::Date();
  1904. }
  1905.  
  1906. TDateTime __fastcall TDateTime::CurrentTime()
  1907. {
  1908.   return Sysutils::Time();
  1909. }
  1910.  
  1911. TDateTime __fastcall TDateTime::CurrentDateTime()
  1912. {
  1913.   return Sysutils::Now();
  1914. }
  1915.  
  1916. TDateTime __fastcall TDateTime::FileDateToDateTime(int fileDate)
  1917. {
  1918.   return Sysutils::FileDateToDateTime(fileDate);
  1919. }
  1920.  
  1921. //ctors
  1922. __fastcall TDateTime::TDateTime(const AnsiString& src, TDateTimeFlag flag)
  1923. {
  1924.   TDateTime tmp;
  1925.   if (flag == DateTime )
  1926.     tmp = Sysutils::StrToDateTime(src);
  1927.   else if (flag == Date)
  1928.     tmp = Sysutils::StrToDate(src);
  1929.   else // flag == Time
  1930.     tmp = Sysutils::StrToTime(src);
  1931.   Val = tmp.Val;
  1932. }
  1933.  
  1934. __fastcall TDateTime::TDateTime(unsigned short year, unsigned short month,
  1935.                                 unsigned short day)
  1936. {
  1937.   TDateTime tmp = Sysutils::EncodeDate(year, month, day);
  1938.   Val = tmp.Val;
  1939. }
  1940.  
  1941. __fastcall TDateTime::TDateTime(unsigned short hour, unsigned short min,
  1942.                                 unsigned short sec, unsigned short msec)
  1943. {
  1944.   TDateTime tmp = Sysutils::EncodeTime(hour, min, sec, msec);
  1945.   Val = tmp.Val;
  1946. }
  1947.  
  1948. //other TDateTime functions
  1949. __fastcall TDateTime::operator AnsiString() const
  1950. {
  1951.   if (Val < 1)
  1952.     return Sysutils::TimeToStr(*this);
  1953.   else if ((Val - int(Val)))
  1954.     return Sysutils::DateTimeToStr(*this);
  1955.   return Sysutils::DateToStr(*this);
  1956.  
  1957. }
  1958.  
  1959. AnsiString __fastcall TDateTime::FormatString(const AnsiString& format)
  1960. {
  1961.   return Sysutils::FormatDateTime(format, *this);
  1962. }
  1963.  
  1964. AnsiString __fastcall TDateTime::DateString() const
  1965. {
  1966.   return Sysutils::DateToStr(*this);
  1967. }
  1968.  
  1969. AnsiString __fastcall TDateTime::TimeString() const
  1970. {
  1971.   return Sysutils::TimeToStr(*this);
  1972. }
  1973.  
  1974. AnsiString __fastcall TDateTime::DateTimeString() const
  1975. {
  1976.   return Sysutils::DateTimeToStr(*this);
  1977. }
  1978.  
  1979. int __fastcall TDateTime::DayOfWeek() const
  1980. {
  1981.   return Sysutils::DayOfWeek(*this);
  1982. }
  1983.  
  1984. int __fastcall TDateTime::FileDate() const
  1985. {
  1986.   return Sysutils::DateTimeToFileDate(*this);
  1987. }
  1988. void __fastcall TDateTime::DecodeDate(unsigned short* year,
  1989.   unsigned short* month, unsigned short* day) const
  1990. {
  1991.   Sysutils::DecodeDate(*this, *year, *month, *day);
  1992. }
  1993. void __fastcall TDateTime::DecodeTime(unsigned short* hour,
  1994.   unsigned short* min, unsigned short* sec, unsigned short* msec) const
  1995. {
  1996.   Sysutils::DecodeTime(*this, *hour, *min, *sec, *msec);
  1997. }
  1998. //-----------------------------------------------------------------------
  1999. __fastcall Currency::Currency(const AnsiString& src)
  2000. {
  2001.   *this = Sysutils::StrToCurr(src);
  2002. }
  2003. //-----------------------------------------------------------------------
  2004. __fastcall Currency::operator AnsiString() const
  2005. {
  2006.   return CurrToStr(*this);
  2007. }
  2008.  
  2009. }
  2010.  
  2011.